"""
Case Type   : 资源池化
Case Name   : 资源池化场景下, 从7.0.0-rc1-b023版本升级至当前最新版本
Create At   : 2025-03-24
Owner       : zhangyuemeng
Description :
    1.执行脚本安装7.0.0-rc1-b023版本集群
    2.运行tpcc业务
    3.执行升级同时运行tpcc业务
    4.执行回滚
    5.再次升级
    6.升级提交
    7.运行tpcc业务
    8.恢复环境
Except      :
    1.安装成功
    2.业务运行正常
    3.升级成功
    4.回滚成功
    5.升级成功
    6.提交成功
    7.业务运行正常
"""
import os
import unittest
import time
from testcase.utils.Logger import Logger
from testcase.utils.Common import Common
from testcase.utils.Constant import Constant
from testcase.utils.ComThread import ComThread
from yat.test import Node
from yat.test import macro

class SharedStorage(unittest.TestCase):
    def setUp(self):
        self.log = Logger()
        self.common = Common()
        self.constant = Constant()
        self.log.info(f'-----{os.path.basename(__file__)} start-----')
        self.pri_root = Node('PrimaryRoot')
        self.pri_user = Node('PrimaryDbUser')

        text = '----查看用户属组----'
        self.log.info(text)
        user_groups = f'groups {self.pri_user.ssh_user}'
        self.log.info(user_groups)
        groups_msg = self.pri_root.sh(user_groups).result()
        self.log.info(groups_msg)
        self.assertIn(f'{self.pri_user.ssh_user}', groups_msg,
                      '执行失败:' + text)
        self.group = groups_msg.split()[2]

    def test_shared_storage(self):
        text = '-----step1: 安装7.0.0-rc1-b023集群-----'
        self.log.info(text)
        self.log.info('-----step1.1: 卸载旧集群-----')
        cmd = f'source {macro.DB_ENV_PATH}; gs_uninstall --delete-data;'
        self.pri_user.sh(cmd)

        self.log.info('-----step1.2: 获取7.0.0-rc1-b023安装包-----')
        om_tgz_name = f'openGauss-OM-7.0.0-*.tar.gz'
        pkg_home = os.path.dirname(macro.DB_PKG_PATH)
        cmd = f'rm -rf {macro.DB_PKG_PATH}; mkdir -p {macro.DB_PKG_PATH}; cd {macro.DB_PKG_PATH}; \
              source /etc/profile; wget {macro.PACKAGE_URL_SECOND}; \
              tar -zxvf {macro.INSTALL_UP_PKG_NAME}; tar -zxvf {om_tgz_name}; \
              chown -R {self.pri_user.ssh_user}:{self.group} {pkg_home};chmod 755 {macro.DB_PKG_PATH}'
        res = self.pri_root.sh(cmd).result()
        self.log.info(res)

        self.log.info('-----step1.3: 执行预安装 expect:预安装成功-----')
        pkg_script = os.path.join(macro.DB_PKG_PATH, 'script')
        preinstall_cmd = f'{pkg_script}/gs_preinstall -U {self.pri_user.ssh_user} \
                         -G {self.group} -X {macro.DB_XML_PATH} --sep-env-file={macro.DB_ENV_PATH}'
        execute_cmd = f'''expect <<EOF
            set timeout 300
            spawn {preinstall_cmd}
            expect "*create trust for root (yes/no)?"
            send "yes\\n"
            expect "*assword*:"
            send "{self.pri_root.ssh_password}\\n"
            expect "*create trust for it (yes/no)?"
            send "yes\\n"
            expect "*assword*:"
            send "{self.pri_root.ssh_password}\\n"
            expect eof\n''' + '''EOF'''
        res = self.pri_root.sh(execute_cmd).result()
        self.assertIn(self.constant.preinstall_success_msg, res, '预安装失败:' + text)

        self.log.info('-----step1.4: 执行gs_install进行安装-----')
        install_cmd = f'gs_install -X {macro.DB_XML_PATH}'
        exec_msg = self.common.do_install(self.pri_user, macro.DB_ENV_PATH, install_cmd)
        self.log.info(exec_msg)

        self.log.info('-----step1.5: 检查集群状态 expect:集群状态正常-----')
        cmd = f'source {macro.DB_ENV_PATH}; cm_ctl query -Cv | grep cluster_state'
        normal_flag = False
        for i in range(10):
            res = self.pri_user.sh(cmd).result()
            if 'Normal' in res:
                normal_flag = True
                self.log.info('The cluster is normal.')
                break
        self.assertTrue(normal_flag, '集群状态异常')

        self.log.info('-----step1.6: 创建tpcc用户-----')
        cmd = f'source {macro.DB_ENV_PATH}; echo $PGPORT'
        port = self.pri_user.sh(cmd).result()
        sql_cmd = "drop user if exists tpcc_user cascade; drop database if exists tpcc; "\
            "create database tpcc;create user tpcc_user with password 'Huawei@123';grant all privileges to tpcc_user;"
        cmd = f'''source {macro.DB_ENV_PATH}; gsql -d postgres -p {port} -c {sql_cmd};
            cm_ctl set --param --server -k log_min_messages="debug5";cm_ctl reload --param --server;'''
        res = self.pri_user.sh(cmd).result()
        self.log.info(res)
        self.log.info('-----step1.7: 导tpcc数据-----')
        cmd = f'cd /data/benchmarksql-5.0/run; ./runDatabaseBuild.sh props_up.pg'
        self.pri_root.sh(cmd)

        text = '-----step2: 运行tpcc-----'
        self.log.info(text)
        tpcc_thread = ComThread(self.common.start_tpcc,
                                args=(self.pri_root, '/data/benchmarksql-5.0/run', './runBenchmark.sh props_up.pg'))
        tpcc_thread.setDaemon(True)
        tpcc_thread.start()
        status = self.pri_root.sh("ps -ux | grep './runBenchmark.sh' | grep -v -- '--color'").result()
        self.assertIn('props_up.pg', status, '执行失败' + text)
        time.sleep(200)

        text = '-----step3: 执行升级-----'
        self.log.info(text)
        text = '-----step3.1: 获取数据库安装包 expect:成功-----'
        self.log.info(text)
        om_tgz_name = f'openGauss-OM-{macro.DB_UPGRADE_VERSION}-*.tar.gz'
        assert len(om_tgz_name.strip()) > 0
        cmd = f'rm -rf {macro.DB_UP_PKG_PATH}; mkdir {macro.DB_UP_PKG_PATH}; cd {macro.DB_UP_PKG_PATH}; \
              source /etc/profile; wget {macro.PACKAGE_UP_URL}; tar -zxvf {macro.INSTALL_UP_PKG_NAME}; \
              tar -zxvf {om_tgz_name}; chown -R {self.pri_user.ssh_user}:{self.group} {macro.DB_UP_PKG_PATH}'
        res = self.pri_root.sh(cmd).result()
        self.log.info(res)

        text = '-----step3.2: 执行预安装 expect:预安装成功-----'
        self.log.info(text)
        upgrade_script = os.path.join(macro.DB_UP_PKG_PATH, 'script')
        preinstall_cmd = f'{upgrade_script}/gs_preinstall -U {self.pri_user.ssh_user} \
                         -G {self.group} -X {macro.DB_XML_PATH} --sep-env-file={macro.DB_ENV_PATH}'
        execute_cmd = f'''expect <<EOF
            set timeout 300
            spawn {preinstall_cmd}
            expect "*create trust for root (yes/no)?"
            send "yes\\n"
            expect "*assword*:"
            send "{self.pri_root.ssh_password}\\n"
            expect "*create trust for it (yes/no)?"
            send "yes\\n"
            expect "*assword*:"
            send "{self.pri_root.ssh_password}\\n"
            expect eof\n''' + '''EOF'''
        res = self.pri_root.sh(execute_cmd).result()
        self.assertIn(self.constant.preinstall_success_msg, res, '预安装失败:' + text)

        text = '-----step3.3: 执行gs_upgradectl升级 expect:升级成功-----'
        self.log.info(text)
        upgrade_cmd = f"source {macro.DB_ENV_PATH}; gs_upgradectl -t auto-upgrade -X {macro.DB_XML_PATH}"
        upgrade_thread = ComThread(self.common.get_sh_result, args=(self.pri_user, upgrade_cmd))
        tpcc_thread = ComThread(self.common.start_tpcc,
                                args=(self.pri_root, '/data/benchmarksql-5.0/run', './runBenchmark.sh props_up.pg'))
        upgrade_thread.setDaemon(True)
        tpcc_thread.setDaemon(True)
        upgrade_thread.start()
        time.sleep(200)
        tpcc_thread.start()
        time.sleep(100)
        upgrade_thread.join()
        upgrade_res = upgrade_thread.get_result()
        self.assertIn('Successfully upgrade all nodes.', upgrade_res, text + '升级失败')

        text = '-----step4: 执行回滚-----'
        self.log.info(text)
        rollback_cmd = f"source {macro.DB_ENV_PATH}; gs_upgradectl -t auto-rollback -X {macro.DB_XML_PATH}"
        res = self.pri_user.sh(rollback_cmd).result()
        self.assertIn('Rollback succeeded.', res, text + '回滚失败')

        text = '-----step5: 再次执行升级 expect:升级成功-----'
        self.log.info(text)
        text = '-----step5.1: 执行预安装 expect:预安装成功-----'
        self.log.info(text)
        upgrade_script = os.path.join(macro.DB_UP_PKG_PATH, 'script')
        preinstall_cmd = f'{upgrade_script}/gs_preinstall -U {self.pri_user.ssh_user} ' \
            f'-G {self.group} -X {macro.DB_XML_PATH} --sep-env-file={macro.DB_ENV_PATH}'
        execute_cmd = f'''expect <<EOF
            set timeout 300
            spawn {preinstall_cmd}
            expect "*create trust for root (yes/no)?"
            send "yes\\n"
            expect "*assword*:"
            send "{self.pri_root.ssh_password}\\n"
            expect "*and create trust for it (yes/no)?"
            send "yes\\n"
            expect "*assword*:"
            send "{self.pri_root.ssh_password}\\n"
            expect eof\n''' + '''EOF'''
        res = self.pri_root.sh(execute_cmd).result()
        self.assertIn(self.constant.preinstall_success_msg, res, '执行失败:' + text)

        text = '-----step5.2: 执行gs_upgradectl升级 expect:升级成功-----'
        self.log.info(text)
        upgrade_cmd = f"source {macro.DB_ENV_PATH}; gs_upgradectl -t auto-upgrade -X {macro.DB_XML_PATH}"
        res = self.pri_user.sh(upgrade_cmd).result()
        self.assertIn('Successfully upgrade all nodes.', res, text + '升级失败')

        text = '-----step6: 执行提交 expect:提交成功-----'
        self.log.info(text)
        commit_cmd = f"source {macro.DB_ENV_PATH}; gs_upgradectl -t commit-upgrade -X {macro.DB_XML_PATH}"
        res = self.pri_user.sh(commit_cmd).result()
        self.assertIn('Commit upgrade succeeded', res, text + '提交失败')

        text = '-----step7: 升级提交后执行tpcc业务 expect:运行tpcc业务正常-----'
        self.log.info(text)
        text = '-----step7.1: 检查集群状态 expect:集群状态正常-----'
        self.log.info(text)
        cmd = f'source {macro.DB_ENV_PATH}; cm_ctl query -Cv'
        res = self.pri_user.sh(cmd).result()
        self.log.info(res)

        text = '-----step7.2: 执行tpcc-----'
        self.log.info(text)
        start_tpcc = ComThread(self.common.start_tpcc,
                                args=(self.pri_root, '/data/benchmarksql-5.0/run', './runBenchmark.sh props_up.pg'))
        start_tpcc.setDaemon(True)
        start_tpcc.start()
        status = self.pri_root.sh("ps -ux | grep './runBenchmark.sh' | grep -v -- '--color'").result()
        self.assertIn('props_up.pg', status, '执行失败' + text)
        time.sleep(30)

    def tearDown(self):
        self.log.info('-----step8: 恢复环境-----')
        stop_cmd = "ps -ef | grep runBenchmark | grep -v grep | awk '{{print $2}}' | xargs kill -9"
        self.pri_root.sh(stop_cmd)
        self.log.info(f'-----{os.path.basename(__file__)} end-----')
